package com.motu.monstercity.server.game.logic;

import com.motu.monstercity.server.game.commondata.act.*;
import com.motu.monstercity.server.game.userdata.UserExtInfo;
import com.motu.monstercity.server.game.verticle.MainVerticle;
import com.motu.vertx.module.utility.mysql.MysqlClient;
import com.motu.vertx.module.utility.mysql.MysqlTool;
import com.motu.vertx.module.utility.toolset.TimeUtils;
import com.motu.vertx.module.utility.toolset.Tool;
import io.vertx.core.CompositeFuture;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.json.JsonArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

public class ActBaseData {
    private static Logger logger = LoggerFactory.getLogger(ActBaseData.class);

    private static ConcurrentHashMap<Long, Act> actList = new ConcurrentHashMap<>(); // 活动信息（key为活动ID）
    private static ConcurrentHashMap<Integer, RegisterSignReward> registerSignRewardMap = new ConcurrentHashMap<>(); // 新手注册签到奖励表


    public static Logger getLogger(){
        return MainVerticle.logger;
    }

    @SuppressWarnings("rawtypes")
    public static void initBaseData(List<Future> futures) {
        futures.add(initAct());
        futures.add(initRegisterSignReward());
        futures.add(initDailySign());
        futures.add(initRaffleDraw());
        futures.add(initDailyPass());  // 初始化高级签到
        futures.add(initDailyPassReward()); // 初始化高级签到奖励
    }

    /*
    所有的节日活动全部加载,用户登录时需要把上一期节日活动未用完的节日徽章兑换成幸运福袋,发邮件给用户
     */
    public static Future<Void> initAct(){
        Promise<Void> promise = Promise.promise();
        String sql = "select * from act where status = 0 and end_time > UNIX_TIMESTAMP() order by end_time;";
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getServerPool(), sql, new JsonArray(), res->{
            if(res.succeeded()){
                ConcurrentHashMap<Long,Act> tmp = new ConcurrentHashMap<Long, Act>();
                JsonArray list = res.result();
                getLogger().info("initAct size:"+list.size());
                String actIds = "";
                List<Future> futures = new ArrayList<>();
                for(int i=0;i<list.size();i++){
                    Act entity = new Act(list.getJsonObject(i));
                    tmp.put(entity.getId(), entity);
                    if (actIds.equals("")) {
                        actIds += entity.getId();
                    } else {
                        actIds += "," + entity.getId();
                    }

                }
                futures.add(initActDetail(tmp, actIds));
                CompositeFuture.all(futures).onComplete(handler->{
                    actList.clear();
                    actList = tmp;
                    promise.complete();
                });

            }else{
                getLogger().error(res.cause().getMessage());
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }

    public static ConcurrentHashMap<Long,Act> getActList(){
        return actList;
    }

    /***
     * 初始化活动明细
     */
    private static Future<Void> initActDetail(ConcurrentHashMap<Long, Act> actTemp, String actIds) {
        Promise<Void> promise = Promise.promise();
        if (actIds.equals("")) {
            promise.complete();
            return promise.future();
        }
        String sql = "select * from act_detail where act_id in (" + actIds + ");";
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getServerPool(), sql, new JsonArray(), res->{
            if(res.succeeded()){
                JsonArray list = res.result();
                getLogger().info("initActDetail size:"+list.size());
                for(int i=0;i<list.size();i++){
                    ActDetail model = new ActDetail(list.getJsonObject(i));
                    Act act = actTemp.get(model.getActId());
                    if (act != null) {
                        act.addDetail(model);
                    }
                }
                promise.complete();
            }else{
                getLogger().error(res.cause().getMessage());
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }


    public static Act getAct(long actId) {
        if(actList.containsKey(actId)) {
            return actList.get(actId);
        }else {
            //getLogger().error("getAct error actId:"+actId);
            return null;
        }
    }

    public static Act getActByType(int type, int serverId) {
        long curTime = TimeUtils.getCurTime();
        int minTime = 946656000;// 2000-01-01 00:00:00（小于这个时间就当做没填写，因为显示时间没填写可能会变成1970年）
        for (Iterator<Act> iter = actList.values().iterator(); iter.hasNext();) {
            Act act = iter.next();
            long startTime = act.getShowTime() < minTime ? act.getStartTime() : act.getShowTime();// 没有填显示时间就用起始时间做判断
            if (act.getType() == type && curTime >= startTime && curTime <= act.getEndTime() && act.isContainServer(serverId)) {
                return act;
            }
        }
        return null;
    }


    /**
     * 初始化新手注册签到奖励表
     */
    public static Future<Void> initRegisterSignReward() {
        String table = "register_sign_reward";
        Promise promise = Promise.promise();
        String sql = "select * from " + table + ";";
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getCommonPool(), sql, new JsonArray(), res -> {
            if (res.succeeded()) {
                try {
                    ConcurrentHashMap<Integer, RegisterSignReward> tmp = new ConcurrentHashMap<>();
                    JsonArray result = res.result();
                    logger.info("init " + table + " size:" + result.size());
                    for (int i = 0; i < result.size(); i++) {
                        RegisterSignReward entity = new RegisterSignReward(result.getJsonObject(i));
                        tmp.put(entity.getId(), entity);
                    }
                    registerSignRewardMap = tmp;
                    promise.complete();
                } catch (Exception e) {
                    logger.error("init " + table + " error exception:" + Tool.getException(e));
                    promise.fail(e);
                }
            } else {
                logger.error(res.cause().getMessage());
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }

    public static RegisterSignReward getRegisterSignReward(int dayIndex) {
        RegisterSignReward registerSignReward = null;
        for (RegisterSignReward reward : registerSignRewardMap.values()) {
            if (reward.getDayNum() == dayIndex) {
                registerSignReward = reward;
                break;
            }
        }
        return registerSignReward;
    }
    public static ConcurrentHashMap<Integer, RegisterSignReward> getRegisterSignRewardMap() { return registerSignRewardMap; }

//    private static ConcurrentHashMap<Integer, DailySign> dailySignMap = new ConcurrentHashMap<>(); // 每日签到配置表
    private static ConcurrentHashMap<Integer, List<DailySign>> dailySignMap = new ConcurrentHashMap<>();

    /**
     * 初始化每日签到配置表
     */
    public static Future<Void> initDailySign() {
        String table = "daily_sign";
        Promise promise = Promise.promise();
        String sql = "select * from " + table + ";";
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getCommonPool(), sql, new JsonArray(), res -> {
            if (res.succeeded()) {
                try {
                    ConcurrentHashMap<Integer, List<DailySign>> tmp = new ConcurrentHashMap<>();
                    JsonArray result = res.result();
                    logger.info("init " + table + " size:" + result.size());
                    for (int i = 0; i < result.size(); i++) {
                        DailySign entity = new DailySign(result.getJsonObject(i));
                        if (!tmp.containsKey(entity.getType())) {
                            List<DailySign> tmp1 = new ArrayList<>();
                            tmp.put(entity.getType(), tmp1);
                        }
                        List<DailySign> tmp1 = tmp.get(entity.getType());
                        tmp1.add(entity);
                    }
                    dailySignMap = tmp;
                    promise.complete();
                } catch (Exception e) {
                    logger.error("init " + table + " error exception:" + Tool.getException(e));
                    promise.fail(e);
                }
            } else {
                logger.error(res.cause().getMessage());
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }

    public static List<DailySign> getDailySignList(int type) {
        return dailySignMap.get(type);
    }

    public static DailySign getDailySign(int type, int day) {
        if (!dailySignMap.containsKey(type)) {
            return null;
        }
        if (day > dailySignMap.get(type).size()) {
            return null;
        }
        return dailySignMap.get(type).get(day - 1);
    }


    private static ConcurrentHashMap<Integer, List<RaffleDraw>> raffleDrawMap = new ConcurrentHashMap<>(); // 每日特惠充值抽奖<期数ID，期数列表>

    /**
     * 初始化每日特惠充值抽奖
     */
    public static Future<Void> initRaffleDraw() {
        String table = "raffle_draw";
        Promise promise = Promise.promise();
        String sql = "select * from " + table + ";";
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getCommonPool(), sql, new JsonArray(), res -> {
            if (res.succeeded()) {
                try {
                    ConcurrentHashMap<Integer, List<RaffleDraw>> tmp = new ConcurrentHashMap<>();
                    JsonArray result = res.result();
                    logger.info("init " + table + " size:" + result.size());
                    for (int i = 0; i < result.size(); i++) {
                        RaffleDraw entity = new RaffleDraw(result.getJsonObject(i));
                        tmp.computeIfAbsent(entity.getGroupId(), k -> new ArrayList<>()).add(entity);
                    }
                    raffleDrawMap = tmp;
                    promise.complete();
                } catch (Exception e) {
                    logger.error("init " + table + " error exception:" + Tool.getException(e));
                    promise.fail(e);
                }
            } else {
                logger.error(res.cause().getMessage());
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }

    public static List<RaffleDraw> getRaffleDrawList(int id) {
        List<RaffleDraw> result = raffleDrawMap.get(id);
        if (result == null || result.isEmpty()) {
            logger.error("getRaffleDraw error key = " + id);
        }
        return result;
    }
    public static ConcurrentHashMap<Integer, List<RaffleDraw>> getRaffleDrawMap() { return raffleDrawMap; }



    private static ConcurrentHashMap<Integer, DailyPass> dailyPassGroupMap = new ConcurrentHashMap<>(); // 高级签到主表
    private static List<Integer> groupList = new ArrayList<>(); // 所有期数
    private static ConcurrentHashMap<Integer, List<DailyPassReward>> dailyPassRewardGroupMap = new ConcurrentHashMap<>(); // 高级签到战令奖励表

    /**
     * 初始化高级签到主表
     */
    public static Future<Void> initDailyPass() {
        String table = "daily_pass";
        Promise promise = Promise.promise();
        String sql = "select * from " + table + ";";
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getCommonPool(), sql, new JsonArray(), res -> {
            if (res.succeeded()) {
                try {
                    ConcurrentHashMap<Integer, DailyPass> tmp = new ConcurrentHashMap<>();
                    List<Integer> tmpList = new ArrayList<>();
                    JsonArray result = res.result();
                    logger.info("init " + table + " size:" + result.size());
                    for (int i = 0; i < result.size(); i++) {
                        DailyPass entity = new DailyPass(result.getJsonObject(i));
                        tmp.put(entity.getRewardId(), entity);
                        tmpList.add(entity.getRewardId());
                    }
                    dailyPassGroupMap = tmp;
                    Collections.sort(tmpList);  // 按照升序
                    groupList = tmpList;
                    promise.complete();
                } catch (Exception e) {
                    logger.error("init " + table + " error exception:" + Tool.getException(e));
                    promise.fail(e);
                }
            } else {
                logger.error(res.cause().getMessage());
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }


    /**
     * 初始化高级签到战令奖励表
     */
    public static Future<Void> initDailyPassReward() {
        String table = "daily_pass_reward";
        Promise promise = Promise.promise();
        String sql = "select * from " + table + ";";
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getCommonPool(), sql, new JsonArray(), res -> {
            if (res.succeeded()) {
                try {
                    ConcurrentHashMap<Integer, List<DailyPassReward>> tmp = new ConcurrentHashMap<>();
                    JsonArray result = res.result();
                    logger.info("init " + table + " size:" + result.size());
                    for (int i = 0; i < result.size(); i++) {
                        DailyPassReward entity = new DailyPassReward(result.getJsonObject(i));
                        tmp.computeIfAbsent(entity.getGroupId(), k -> new ArrayList<>()).add(entity);
                    }
                    dailyPassRewardGroupMap = tmp;
                    promise.complete();
                } catch (Exception e) {
                    logger.error("init " + table + " error exception:" + Tool.getException(e));
                    promise.fail(e);
                }
            } else {
                logger.error(res.cause().getMessage());
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }

    // 最后的期数
    public static int getDailyPassMaxGroupId(){
        if (groupList == null || groupList.isEmpty()) {
            return -1; // 或 throw new IllegalArgumentException("分组列表为空");
        }
        return groupList.getLast();
    }

    // 开始的期数
    public static int getDailyPassStartGroupId(){
        if (groupList == null || groupList.isEmpty()) {
            return -1; // 或 throw new IllegalArgumentException("分组列表为空");
        }
        return groupList.getFirst();
    }

    /**
     * 获取当前分组ID的下一个分组ID（升序排列）
     * @param groupId 当前分组ID
     * @return 下一个分组ID，如果已是最后一个则返回-1（或自定义默认值）
     */
    public static int getDailyPassNextGroupId(int groupId) {
        if (groupList == null || groupList.isEmpty()) {
            return -1; // 或 throw new IllegalArgumentException("分组列表为空");
        }

        // 确保列表是升序排序（如果未提前排序）
        Collections.sort(groupList);

        // 查找当前groupId的索引
        int currentIndex = groupList.indexOf(groupId);
        if (currentIndex == -1) {
            return -1; // 当前groupId不存在
        }

        // 检查是否已是最后一个元素
        if (currentIndex == groupList.size() - 1) {
            return -1; // 无下一个分组
        }

        // 返回下一个分组ID
        return groupList.get(currentIndex + 1);
    }


    public static DailyPass getDailyPassConfigByGroupId(int groupId) {
        DailyPass result = dailyPassGroupMap.get(groupId);
        if (result == null) {
            logger.error("getDailyPass error key = " + groupId);
        }
        return result;
    }
    public static ConcurrentHashMap<Integer, DailyPass> getDailyPassGroupMap() { return dailyPassGroupMap; }

    /**
     * 获取高级签到当前期的配置  没有则当前还没有期数
     */
    public static DailyPass getCurDailyPassConfig(long registerTime) {
        // 获取当前的期数
        long curTime = TimeUtils.getCurTime();
        ConcurrentHashMap<Integer, DailyPass> dailyPassGroupMap = getDailyPassGroupMap();
        for (DailyPass dailyPass:dailyPassGroupMap.values()){
            long tempStartTime = getDailyPassStartTime(registerTime,dailyPass);
            long tempEndTime =  getDailyPassEndTime(registerTime, dailyPass);
            if (curTime >= tempStartTime && curTime <= tempEndTime) {
                return dailyPass;
            }
        }
        return null;
    }

    // 判断是否在有效期内合法性
    public static boolean checkDailyPassValid(int groupId,long registerTime){
        DailyPass config = getDailyPassConfigByGroupId(groupId);
        if (config == null) {return false;}
        long curTime = TimeUtils.getCurTime();
        // 在有效期内，判断今日是否领取过奖励
        return curTime >= getDailyPassStartTime(registerTime, config) && curTime <= getDailyPassEndTime(registerTime, config);
    }

    public static long getDailyPassStartTime(long registerTime,DailyPass dailyPass){
        long startTime = TimeUtils.getStartTimeOfDay(registerTime);
        return  startTime + (long) Tool.DAY * dailyPass.getStartDay();
    }

    public static long getDailyPassEndTime(long registerTime,DailyPass dailyPass){
        long startTime = TimeUtils.getStartTimeOfDay(registerTime);
        return  startTime + (long) Tool.DAY * (dailyPass.getEndDay() + 1);  // 因为是24点所以多加一天
    }




    // 获取期数对应所有天数配置奖励
    public static List<DailyPassReward> getDailyPassGroupReward(int groupId) {
        List<DailyPassReward> result = dailyPassRewardGroupMap.get(groupId);
        if (result == null) {
            logger.error("getDailyPassGroupReward error key = " + groupId);
        }
        return result;
    }

    // 按照期数和对应的天数获取具体奖励
    public static DailyPassReward getDailyPassGroupReward(int groupId,int day) {
        List<DailyPassReward> result = dailyPassRewardGroupMap.get(groupId);
        if (result == null) {
            logger.error("getDailyPassGroupReward error key = " + groupId);
            return null;
        }
        for (DailyPassReward passReward:result){
            if (passReward.getDay() == day) {
                return passReward;
            }
        }
        return null;
    }
}
